#!/bin/bash

# 多人贪吃蛇大作战 - 启动脚本
# 作者：游戏开发专家
# 用途：快速启动和管理游戏服务器

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 项目信息
PROJECT_NAME="snake-game"
PORT=13000
LOG_FILE="game.log"

# 打印带颜色的消息
print_message() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

print_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

print_title() {
    echo -e "${BLUE}================================${NC}"
    echo -e "${BLUE}    浪浪山多人贪吃蛇大作战服务器${NC}"
    echo -e "${BLUE}================================${NC}"
}

# 检查Node.js是否安装
check_nodejs() {
    if ! command -v node &> /dev/null; then
        print_error "Node.js 未安装，请先安装 Node.js 14.0 或更高版本"
        exit 1
    fi
    
    NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
    if [ "$NODE_VERSION" -lt 14 ]; then
        print_error "Node.js 版本过低，需要 14.0 或更高版本，当前版本：$(node --version)"
        exit 1
    fi
    
    print_message "Node.js 版本检查通过：$(node --version)"
}

# 检查npm是否安装
check_npm() {
    if ! command -v npm &> /dev/null; then
        print_error "npm 未安装，请先安装 npm"
        exit 1
    fi
    print_message "npm 版本：$(npm --version)"
}

# 安装依赖
install_dependencies() {
    print_message "正在安装项目依赖..."
    if [ -f "package.json" ]; then
        npm install
        print_message "依赖安装完成"
    else
        print_error "未找到 package.json 文件"
        exit 1
    fi
}

# 检查端口是否被占用
check_port() {
    if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then
        print_warning "端口 $PORT 已被占用"
        PID=$(lsof -Pi :$PORT -sTCP:LISTEN -t)
        print_warning "占用进程 PID: $PID"
        read -p "是否要终止占用进程？(y/N): " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            kill -9 $PID
            print_message "已终止进程 $PID"
        else
            print_error "无法启动服务器，端口被占用"
            exit 1
        fi
    fi
}

# 启动开发服务器
start_dev() {
    print_message "启动开发服务器..."
    check_port
    print_message "服务器启动中，访问地址：http://localhost:$PORT"
    print_message "按 Ctrl+C 停止服务器"
    node server.js
}

# 后台启动服务器
start_background() {
    print_message "后台启动服务器..."
    check_port
    nohup node server.js > $LOG_FILE 2>&1 &
    PID=$!
    echo $PID > server.pid
    print_message "服务器已在后台启动，PID: $PID"
    print_message "访问地址：http://localhost:$PORT"
    print_message "日志文件：$LOG_FILE"
    print_message "使用 './start.sh stop' 停止服务器"
}

# 停止服务器
stop_server() {
    if [ -f "server.pid" ]; then
        PID=$(cat server.pid)
        if ps -p $PID > /dev/null 2>&1; then
            kill $PID
            rm server.pid
            print_message "服务器已停止 (PID: $PID)"
        else
            print_warning "服务器进程不存在 (PID: $PID)"
            rm server.pid
        fi
    else
        print_warning "未找到服务器 PID 文件"
        # 尝试通过端口查找并停止
        if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then
            PID=$(lsof -Pi :$PORT -sTCP:LISTEN -t)
            kill $PID
            print_message "已停止占用端口 $PORT 的进程 (PID: $PID)"
        else
            print_message "没有发现运行中的服务器"
        fi
    fi
}

# 重启服务器
restart_server() {
    print_message "重启服务器..."
    stop_server
    sleep 2
    start_background
}

# 查看服务器状态
status_server() {
    print_title
    
    if [ -f "server.pid" ]; then
        PID=$(cat server.pid)
        if ps -p $PID > /dev/null 2>&1; then
            print_message "服务器运行中 (PID: $PID)"
            print_message "访问地址：http://localhost:$PORT"
            
            # 显示内存和CPU使用情况
            if command -v ps &> /dev/null; then
                MEMORY=$(ps -p $PID -o rss= | awk '{print $1/1024 " MB"}')
                CPU=$(ps -p $PID -o %cpu= | awk '{print $1"%"}')
                print_message "内存使用：$MEMORY"
                print_message "CPU使用：$CPU"
            fi
        else
            print_warning "PID 文件存在但进程不运行 (PID: $PID)"
            rm server.pid
        fi
    else
        print_message "服务器未运行"
    fi
    
    # 检查端口状态
    if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then
        PORT_PID=$(lsof -Pi :$PORT -sTCP:LISTEN -t)
        print_message "端口 $PORT 被进程 $PORT_PID 占用"
    else
        print_message "端口 $PORT 空闲"
    fi
}

# 查看日志
view_logs() {
    if [ -f "$LOG_FILE" ]; then
        print_message "显示最近50行日志："
        tail -n 50 $LOG_FILE
    else
        print_warning "日志文件不存在：$LOG_FILE"
    fi
}

# 实时查看日志
follow_logs() {
    if [ -f "$LOG_FILE" ]; then
        print_message "实时查看日志（按 Ctrl+C 退出）："
        tail -f $LOG_FILE
    else
        print_warning "日志文件不存在：$LOG_FILE"
    fi
}

# PM2 管理
setup_pm2() {
    if ! command -v pm2 &> /dev/null; then
        print_message "安装 PM2..."
        npm install -g pm2
    fi
    
    print_message "使用 PM2 启动服务器..."
    pm2 start server.js --name "$PROJECT_NAME" --watch
    pm2 save
    print_message "PM2 启动完成"
    print_message "常用 PM2 命令："
    echo "  pm2 list                    # 查看所有进程"
    echo "  pm2 logs $PROJECT_NAME      # 查看日志"
    echo "  pm2 restart $PROJECT_NAME   # 重启"
    echo "  pm2 stop $PROJECT_NAME      # 停止"
    echo "  pm2 delete $PROJECT_NAME    # 删除"
}

# 运行健康检查
run_health_check() {
    print_message "🔍 运行服务器健康检查..."
    
    if [ -f "./health-check.sh" ]; then
        ./health-check.sh --check
    else
        print_error "❌ 健康检查脚本不存在"
        exit 1
    fi
}

# 启动监控模式
start_monitor() {
    print_message "📊 启动服务器监控模式..."
    
    if [ -f "./health-check.sh" ]; then
        ./health-check.sh --monitor 60
    else
        print_error "❌ 健康检查脚本不存在"
        exit 1
    fi
}

# 备份项目文件
backup_project() {
    print_message "💾 备份项目文件..."
    
    local backup_dir="./backups"
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local backup_file="$backup_dir/snake-game-backup-$timestamp.tar.gz"
    
    # 创建备份目录
    mkdir -p "$backup_dir"
    
    # 创建备份
    tar -czf "$backup_file" \
        --exclude="node_modules" \
        --exclude="logs" \
        --exclude="backups" \
        --exclude=".git" \
        .
    
    if [ $? -eq 0 ]; then
        print_message "✅ 备份完成: $backup_file"
        
        # 清理旧备份（保留最近7个）
        find "$backup_dir" -name "snake-game-backup-*.tar.gz" -type f | \
            sort -r | tail -n +8 | xargs rm -f
        
        print_message "📁 备份目录: $backup_dir"
        ls -la "$backup_dir"
    else
        print_error "❌ 备份失败"
        exit 1
    fi
}

# 更新项目依赖
update_dependencies() {
    print_message "🔄 更新项目依赖..."
    
    # 检查 package.json 是否存在
    if [ ! -f "package.json" ]; then
        print_error "❌ package.json 不存在"
        exit 1
    fi
    
    # 备份当前的 package-lock.json
    if [ -f "package-lock.json" ]; then
        cp package-lock.json package-lock.json.backup
        print_message "📋 已备份 package-lock.json"
    fi
    
    # 更新依赖
    print_message "📦 正在更新依赖..."
    npm update
    
    if [ $? -eq 0 ]; then
        print_message "✅ 依赖更新完成"
        
        # 显示更新的包
        print_message "📊 检查过时的包:"
        npm outdated || true
        
        print_message "🔍 运行安全审计:"
        npm audit || true
    else
        print_error "❌ 依赖更新失败"
        
        # 恢复备份
        if [ -f "package-lock.json.backup" ]; then
            mv package-lock.json.backup package-lock.json
            print_message "🔄 已恢复 package-lock.json 备份"
        fi
        
        exit 1
    fi
}

# 显示帮助信息
show_help() {
    print_title
    echo "用法: $0 [命令]"
    echo ""
    echo "命令:"
    echo "  dev        启动开发服务器（前台运行）"
    echo "  start      后台启动服务器"
    echo "  stop       停止服务器"
    echo "  restart    重启服务器"
    echo "  status     查看服务器状态"
    echo "  logs       查看日志"
    echo "  follow     实时查看日志"
    echo "  install    安装依赖"
    echo "  pm2        使用 PM2 管理服务器"
    echo "  health     运行健康检查"
    echo "  monitor    启动监控模式"
    echo "  backup     备份项目文件"
    echo "  update     更新项目依赖"
    echo "  help       显示此帮助信息"
    echo ""
    echo "示例:"
    echo "  $0 install    # 安装依赖"
    echo "  $0 dev        # 开发模式启动"
    echo "  $0 start      # 后台启动"
    echo "  $0 status     # 查看状态"
    echo "  $0 pm2        # 使用 PM2 管理"
    echo "  $0 health     # 运行健康检查"
    echo "  $0 monitor    # 启动监控模式"
}

# 主函数
main() {
    # 检查基础环境
    check_nodejs
    check_npm
    
    case "${1:-help}" in
        "dev")
            install_dependencies
            start_dev
            ;;
        "start")
            install_dependencies
            start_background
            ;;
        "stop")
            stop_server
            ;;
        "restart")
            restart_server
            ;;
        "status")
            status_server
            ;;
        "logs")
            view_logs
            ;;
        "follow")
            follow_logs
            ;;
        "install")
            install_dependencies
            ;;
        "pm2")
            install_dependencies
            setup_pm2
            ;;
        "health")
            run_health_check
            ;;
        "monitor")
            start_monitor
            ;;
        "backup")
            backup_project
            ;;
        "update")
            update_dependencies
            ;;
        "help")
            show_help
            ;;
        *)
            print_error "未知命令: $1"
            show_help
            exit 1
            ;;
    esac
}

# 运行主函数
main "$@"